"""
Recursive Problem Solving

Complete all functions below. Do not modify function names or parameters.
Test your code using the test cases at the bottom of the file.

IMPORTANT: All solutions must use RECURSION (no loops allowed in main logic!)
"""


# ============================================================================
# TASK 1: Count Elements in a List (20 points)
# ============================================================================

def count_elements(L):
    """
    Counts the number of elements in a list recursively.

    Args:
        L: A list

    Returns:
        Integer count of elements

    Example:
        >>> count_elements([1, 2, 3, 4, 5])
        5
        >>> count_elements([])
        0
    """
    # TODO: Implement this function recursively
    # Think about:
    # - What should happen when the list is empty? (base case)
    # - How can you break down the problem into a smaller version?
    # - What is the count of one element plus the count of the rest?
    if L==[]:
        return 0
    else:
        return 1 + count_elements(L[1:])
      # Replace this with your implementation
print("COUNT TEST")
print(count_elements([100]))
# ============================================================================
# TASK 2: Reverse a String (20 points)
# ============================================================================

def reverse_string(s):
    """
    Reverses a string recursively.

    Args:
        s: A string

    Returns:
        Reversed string

    Example:
        >>> reverse_string("hello")
        "olleh"
        >>> reverse_string("")
        ""
    """
    # TODO: Implement this function recursively
    # Think about:
    # - What should happen when the string is empty or has one character? (base case)
    # - How can you combine one character with the reversed rest of the string?
    # - You can use string slicing to get parts of the string
    if len(s)==0:
        return ""
    elif len(s)==1:
        return s
    else:
        return s[-1] + reverse_string(s[:-1])
print(reverse_string("hocalarim cok yakisikli"))# Replace this with your implementation


# ============================================================================
# TASK 3: Flatten Nested Lists (30 points)
# ============================================================================

def flatten(L):
    """
    Flattens a list of lists into a single list.

    Args:
        L: A list of lists (one level deep)

    Returns:
        A flattened list

    Example:
        >>> flatten([[1, 2], [3, 4], [5, 6, 7]])
        [1, 2, 3, 4, 5, 6, 7]
        >>> flatten([[10], [20], [30]])
        [10, 20, 30]
    """
    # TODO: Implement this function recursively
    # Think about:
    # - What should happen when there's only one sublist left? (base case)
    # - How can you combine the first sublist with the flattened rest?
    # - Remember: you can concatenate lists with the + operator
    #alternative with correct base case
    if len(L)==1:
        return L[0]
    else:
        return L[0] +flatten(L[1:])


      # Replace this with your implementation
print("FLATTEN TEST")
print(flatten([["a","b"],["c"]]))
# ============================================================================
# TASK 4: Deep Sum of Nested Lists (30 points)
# ============================================================================

def deep_sum(L):
    """
    Calculates the sum of all numbers in a deeply nested list.

    Args:
        L: A potentially deeply nested list

    Returns:
        Sum of all numbers in the list

    Example:
        >>> deep_sum([1, [2, 3], 4])
        10  # 1 + 2 + 3 + 4
        >>> deep_sum([1, [2, [3, [4]]]])
        10  # 1 + 2 + 3 + 4
        >>> deep_sum([[[[10]]]])
        10
    """
    # TODO: Implement this function recursively
    # Think about:
    # - What should happen when the list is empty? (base case)
    # - How do you handle an element that is itself a list?
    # - How do you handle an element that is a number?
    # - You can check if something is a list using: type(x) == list
    # - You'll need to process the first element AND the rest of the list

    if L == []:
        return 0
    elif type(L[0])== list:
        return deep_sum(L[0]) + deep_sum(L[1:])
    else:
        return L[0] + deep_sum(L[1:])
print(deep_sum([[1,2],[[[3]]]]))

# ============================================================================
# TEST CASES - Run these to test your implementations
# ============================================================================

if __name__ == "__main__":
    print("=" * 70)
    print("EE103 Lab 9: Recursive Problem Solving")
    print("=" * 70)

    # Test Task 1
    print("\n--- Task 1: Count Elements (20 points) ---")
    try:
        tests_1 = [
            ([1, 2, 3, 4, 5], 5),
            (['a', 'b', 'c'], 3),
            ([100], 1),
            ([], 0)
        ]

        passed = 0
        for test_input, expected in tests_1:
            result = count_elements(test_input)
            if result == expected:
                print(f"  ✓ count_elements({test_input}) = {result}")
                passed += 1
            else:
                print(f"  ✗ count_elements({test_input}) = {result} (expected {expected})")

        if passed == len(tests_1):
            print(f"  ✓ Task 1: {passed}/{len(tests_1)} tests passed - COMPLETE!")
        elif passed == 0:
            print(f"  ✗ Task 1: {passed}/{len(tests_1)} tests passed - NOT STARTED")
            print(f"     → Implement base case (empty list) and recursive case!")
        else:
            print(f"  ⚠ Task 1: {passed}/{len(tests_1)} tests passed - needs work")
            print(f"     → Check both base case AND recursive case!")
    except Exception as e:
        print(f"  ✗ Error in Task 1: {e}")

    # Test Task 2
    print("\n--- Task 2: Reverse String (20 points) ---")
    try:
        tests_2 = [
            ("hello", "olleh"),
            ("Python", "nohtyP"),
            ("a", "a"),
            ("", ""),
            ("racecar", "racecar")
        ]

        passed = 0
        for test_input, expected in tests_2:
            result = reverse_string(test_input)
            if result == expected:
                print(f"  ✓ reverse_string('{test_input}') = '{result}'")
                passed += 1
            else:
                print(f"  ✗ reverse_string('{test_input}') = '{result}' (expected '{expected}')")

        if passed == len(tests_2):
            print(f"  ✓ Task 2: {passed}/{len(tests_2)} tests passed - COMPLETE!")
        elif passed == 0:
            print(f"  ✗ Task 2: {passed}/{len(tests_2)} tests passed - NOT STARTED")
            print(f"     → Implement base case and recursive case!")
        else:
            print(f"  ⚠ Task 2: {passed}/{len(tests_2)} tests passed - needs work")
            print(f"     → Check both base case AND recursive case!")
    except Exception as e:
        print(f"  ✗ Error in Task 2: {e}")

    # Test Task 3
    print("\n--- Task 3: Flatten Lists (30 points) ---")
    try:
        tests_3 = [
            ([[1, 2], [3, 4], [5, 6, 7]], [1, 2, 3, 4, 5, 6, 7]),
            ([[10], [20], [30]], [10, 20, 30]),
            ([['a', 'b'], ['c']], ['a', 'b', 'c'])
        ]

        passed = 0
        for test_input, expected in tests_3:
            result = flatten(test_input)
            if result == expected:
                print(f"  ✓ flatten({test_input}) = {result}")
                passed += 1
            else:
                print(f"  ✗ flatten({test_input}) = {result}")
                print(f"     Expected: {expected}")

        if passed == len(tests_3):
            print(f"  ✓ Task 3: {passed}/{len(tests_3)} tests passed - COMPLETE!")
        elif passed == 0:
            print(f"  ✗ Task 3: {passed}/{len(tests_3)} tests passed - NOT STARTED")
            print(f"     → Implement base case and recursive case!")
        else:
            print(f"  ⚠ Task 3: {passed}/{len(tests_3)} tests passed - needs work")
            print(f"     → Check both base case AND recursive case!")
    except Exception as e:
        print(f"  ✗ Error in Task 3: {e}")

    # Test Task 4
    print("\n--- Task 4: Deep Sum (30 points) ---")
    try:
        tests_4 = [
            ([1, [2, 3], 4], 10),           # Simple nesting
            ([1, 2, 3], 6),                 # No nesting (flat list)
            ([[1, 2], [[3]]], 6),           # Multiple levels
            ([[[[10]]]], 10),               # Very deep
            ([1, [2, [3, [4]]]], 10)        # Progressive nesting
        ]

        passed = 0
        for test_input, expected in tests_4:
            result = deep_sum(test_input)
            if result == expected:
                print(f"  ✓ deep_sum({test_input}) = {result}")
                passed += 1
            else:
                print(f"  ✗ deep_sum({test_input}) = {result} (expected {expected})")

        if passed == len(tests_4):
            print(f"  ✓ Task 4: {passed}/{len(tests_4)} tests passed - COMPLETE!")
        elif passed == 0:
            print(f"  ✗ Task 4: {passed}/{len(tests_4)} tests passed - NOT STARTED")
            print(f"     → Implement base case and recursive cases!")
        else:
            print(f"  ⚠ Task 4: {passed}/{len(tests_4)} tests passed - needs work")
            print(f"     → Check base case and both recursive cases!")
    except Exception as e:
        print(f"  ✗ Error in Task 4: {e}")

    # Summary
    print("\n" + "=" * 70)
    print("Testing Complete!")
    print("=" * 70)
    print("\nSymbol Legend:")
    print("  ✓ = Test passed")
    print("  ✗ = Test failed")
    print("  ⚠ = Some tests passed, some failed")
    print("\nMake sure all tasks show ' COMPLETE!' before submitting!")
    print("=" * 70)
